package com.twodstar.selfie;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import com.facebook.Session;
import com.facebook.SessionDefaultAudience;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphUser;
import com.parse.GetCallback;
import com.parse.ParseException;
import com.parse.ParseFacebookUtils;
import com.parse.ParseUser;
import com.parse.PushService;
import com.twodstar.selfie.R;
import com.twodstar.selfie.slidemenu.BaseActivity;

public class MainActivity extends BaseActivity 
{
	
	private static final int USER_INFO_REFRESH_DELAY = 4;
	public static final int SPLASH = 1;
	public static final int SELECTION = 2;
    public static final int SETTINGS = 3;
    public static final int BATTLES = 4;
    public static final int BEST = 5;
    public static final int ABOUT = 6;    
    private static boolean m_IsOnBackground = false;
    private static final String PERMISSION = "publish_actions";
    private static boolean m_IsTickCreated = false;
    private static final int AD_DRUATION = 60 * 5;
    
    private int m_ToShowFrag = 0;    
    private boolean m_IsParseUserInfoFetched = false;
    private int m_UserInfoRefershCounter  = 0;
    private int m_AdTimer = AD_DRUATION;   
    private UiLifecycleHelper uiHelper;
    
    private Session.StatusCallback sessionCallback = new Session.StatusCallback() 
												    {
												        @Override
												        public void call(final Session session, final SessionState state, final Exception exception) 
												        {
												            onSessionStateChange(session, state, exception);
												        }
												    };
												    
    private void onSessionStateChange(final Session session, SessionState state, Exception exception) 
    {
        Fragment_NewBattle.Instance().onSessionStateChange(session, state, exception);
        Fragment_Battles.Instance().onSessionStateChange(session, state, exception);
        Fragment_Best.Instace().onSessionStateChange(session, state, exception);
    }				
	
    @Override
    protected void onResume() 
    {
    	// TODO Auto-generated method stub
    	SetLocale();
    	
    	super.onResume();
    	m_IsOnBackground = false;
    	uiHelper.onResume();
    	
    	if(SelfieBattleApplication.Instance() != null && SelfieBattleApplication.Instance().isOnline() == false)
    	{
    		SelfieBattleApplication.Instance().LogoutUser();
    		showFragment(SPLASH);
    	}    	
    	else if(m_ToShowFrag > 0)
    	{
    		showFragment(m_ToShowFrag);
    		
    		if(m_ToShowFrag == BATTLES)
    		{
    			Fragment_Battles.Instance().ForceRefreshLike(1);
    		}
    	}
    }
    
    
    
    
    public void SetLocale()
    {
    	if(SelfieBattleApplication.Instance().GetIsParseInited() == false)
    		return;
    	 
    	ParseUser PU =  ParseUser.getCurrentUser();
    	if( PU == null)
    		return;
    	
    	String Country = PU.getString("Country");
    	
    	if(Country == null)
    		return;
    	
    	boolean B1 = Country.toLowerCase().contains("myanmar");
    	boolean B2 = Country.toLowerCase().contains("burma");
    	boolean B3 = Country.contains( getResources().getString(R.string.myanmar) );
    	
    	if(B1 || B2 || B3)
    	{}
    	else
    	{
    		return;
    	}
    	
    	Locale locale = new Locale("my");
    	Locale.setDefault(locale);
    	Configuration config = new Configuration();
    	config.locale = locale;
    	
    	if(  getBaseContext() != null && getBaseContext().getResources() != null)
    		getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
    	
    }
    
    public void Reset()
    {
    	m_IsParseUserInfoFetched = false;
    }
    
    
    @Override
    protected void onPause() 
    {
    	// TODO Auto-generated method stub
    	super.onPause();
    	m_IsOnBackground = true;
    	uiHelper.onPause();
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState) 
    {
    	// TODO Auto-generated method stub
    	super.onSaveInstanceState(outState);
    	uiHelper.onSaveInstanceState(outState);
    	
    	outState.putInt("m_ToShowFrag", m_ToShowFrag);
    	outState.putInt("m_UserInfoRefershCounter", m_UserInfoRefershCounter);
    	outState.putInt("m_AdTimer", m_AdTimer);
    	outState.putBoolean("m_IsParseUserInfoFetched", m_IsParseUserInfoFetched);   
    	
    	if (SelfieBattleApplication.Instance().getSelectedUsers() != null) 
    	{
    		outState.putByteArray("SelectedUsers" , getByteArray(SelfieBattleApplication.Instance().getSelectedUsers()));
        }
    	
    	Fragment_NewBattle.Instance().CustomSaveInstanceState(outState);
    	
    }
    
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) 
    {
    	// TODO Auto-generated method stub
    	super.onRestoreInstanceState(savedInstanceState);
    	
    	m_ToShowFrag = savedInstanceState.getInt("m_ToShowFrag");
    	m_UserInfoRefershCounter = savedInstanceState.getInt("m_UserInfoRefershCounter");
    	m_AdTimer = savedInstanceState.getInt("m_AdTimer");
    	savedInstanceState.getBoolean("m_IsParseUserInfoFetched");
    	
    	byte[] bytes = savedInstanceState.getByteArray("SelectedUsers");
        if (bytes != null) 
        {
            SelfieBattleApplication.Instance().setSelectedUsers(restoreByteArray(bytes));            
        }
    	
        Fragment_NewBattle.Instance().CustomRestoreInstanceState(savedInstanceState);
    }
    

    
    public static boolean IsOnbackground()
    {
    	return m_IsOnBackground;
    }
    
    void handleSendImage(Intent intent) 
    {
    	PBUtility.LOG("Share via selfie battle 1");
        Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
        if (imageUri != null) 
        {
        	 PBUtility.LOG("Share via selfie battle 2");
            // Update UI to reflect image being shared
        	Fragment_NewBattle.Instance().SetPhotoRUI(imageUri);
        }
    }

    
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		
		super.onCreate(savedInstanceState);
		
		//if(savedInstanceState != null)
		//	return;
		

		Fragment_NewBattle.Recreated();
		Fragment_Battles.Recreated();
		Fragment_Best.Recreated();
		Fragment_About.Recreated();
		Fragment_Login.Recreated();
		
		Intent intent = getIntent();
	    String action = intent.getAction();
	    String type = intent.getType();

		if (Intent.ACTION_SEND.equals(action) && type != null) 
		{
	        if (type.startsWith("image/")) 
	        {
	            handleSendImage(intent); // Handle single image being sent
	        }
	    } 
		
	
	
		
		PBUtility.LOG("On Create ---------------------------");
		SntpClient.GetTimeUTC();		
		PushService.setDefaultPushCallback(this, MainActivity.class);                           
 		ParseUser currentUser = ParseUser.getCurrentUser();
 		
 		if(SelfieBattleApplication.Instance().isOnline() == false)
 		{
 			PBUtility.LOG("no connection!"); 	        
	 		showFragment(SPLASH);
 		}
 		else if ((currentUser != null) && ParseFacebookUtils.isLinked(currentUser)) 
 		{
 			Session session = ParseFacebookUtils.getSession(); 			
 	        if ( session != null && session.isOpened()  ) 
 	        { 	       	
 	 	    	
 	    		int BattleCount = currentUser.getInt("TotalBattle");
 	    		if(BattleCount > 0)
 	    		{
 	    			//PBUtility.LOG("showFragment(BATTLES, false);");
 	    			ShowSelection();
 	    			//showFragment(BATTLES); 	    			
 	    		}
 	    		else 
 	    		{ 	    			
 	    			PBUtility.LOG("ShowSelection()"); 	
 	    			ShowSelection();
 	    		} 	 	    	
 	           
 	        }
 	        else
 	        {
 	        	PBUtility.LOG("session is not open"); 	        
 	 			showFragment(SPLASH);
 	        } 			
 			
 			
 		}
 		else
 		{
 			PBUtility.LOG("ask to log in: no current user!"); 			
 			showFragment(SPLASH);
 		}
 		
 		 uiHelper = new UiLifecycleHelper(this, sessionCallback);
         uiHelper.onCreate(savedInstanceState);         
         
         
         if(m_IsTickCreated == false)
         {
        	 m_IsTickCreated = true;
	         final Handler handler = new Handler();
	         Timer timer = new Timer(false);
	         TimerTask timerTask = new TimerTask() 
	         {
	             @Override
	             public void run() 
	             {
	                 handler.post(new Runnable() 
	                 {
	                     @Override
	                     public void run() 
	                     {
	                        Tick();                    		
	                     }
	                 });
	             }
	         };
	         timer.scheduleAtFixedRate(timerTask, 0, 1000);
         }
         
         if(ParseUser.getCurrentUser() != null && ParseUser.getCurrentUser().getString("FBID") != null &&  ParseUser.getCurrentUser().getString("FBID").isEmpty() == false )
         {
        	 SelfieBattleApplication app = SelfieBattleApplication.Instance();
        	 app.SetFBID(ParseUser.getCurrentUser().getString("FBID"));
         }
        
	}
	
	
	private void Tick()
	{
		m_AdTimer--;
		if(m_AdTimer < -1)
		{
			m_AdTimer = 2;
		}
		
		Fragment_Battles.Instance().Tick();
		
		if(m_IsOnBackground)
			return;
		
		
		
		if(m_UserInfoRefershCounter > 0)
		{
			m_UserInfoRefershCounter--;
			if(m_UserInfoRefershCounter <=0)
			{
				UpdatePlayerInfo(true);
			}
		}
		
		
		if(m_AdTimer <= 0)
		{
			m_AdTimer = AD_DRUATION;
			
			if(ParseUser.getCurrentUser() != null)
			{
				if(ParseUser.getCurrentUser().getInt("TotalBattle") < 1)
					return;
				
				AdRequestFullScreen();
			}
		}
		
	}
	
	public void SetDelayUpdatePlayerInfo()
	{
		m_UserInfoRefershCounter = USER_INFO_REFRESH_DELAY;
	}
	
	/*
	private boolean IsShowingThis()
	{
		ArrayList<String> runningactivities = new ArrayList<String>();
	
		ActivityManager activityManager = (ActivityManager)getBaseContext().getSystemService (Context.ACTIVITY_SERVICE); 
	
		List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE); 
	
		for (int i1 = 0; i1 < services.size(); i1++) 
		{ 
		    runningactivities.add(0,services.get(i1).topActivity.toString());  
		} 

	
		if(runningactivities.contains("ComponentInfo{com.app/com.towdstar.selfie..MainActivity}")==true)
		{
			return true;
		}
		return false;
	}
	*/
	
	public void showFragment(int ID)
	{
		if(IsOnbackground())
		{
			m_ToShowFrag  = ID;
			return;
		}
		
		//if(IsShowingThis() == false)
		//	return;
		
		m_ToShowFrag = 0;
		if(getSupportActionBar().isShowing() == false)
			getSupportActionBar().show();
		
		
		
		switch(ID)
		{
		case SELECTION:
			ShowSelection();
			break;
		
		case SPLASH:
			switchContent(Fragment_Login.Instance());
			
			if(getSupportActionBar()!= null)
				getSupportActionBar().hide();
			
			if(getSlidingMenu() != null )
				getSlidingMenu().setSlidingEnabled(false);
			
			break;
			
		case BATTLES:
			SelfieBattleApplication.Instance().LoadAPPFriendList();
			switchContent(Fragment_Battles.Instance());
			break;
			
		case BEST:
			switchContent(Fragment_Best.Instace());			
			SelfieBattleApplication.Instance().LoadAPPFriendList();
			Fragment_Best.Instace().GetBestListAfterGettingFrdList();
	    	
			break;
			
		case ABOUT:
			switchContent(Fragment_About.Instance());
			break;
			
					
		
		}
		//switchContent(fragment);
		
		if(getSlidingMenu() != null  && ID != SPLASH)
			getSlidingMenu().setSlidingEnabled(true);
	}
	
	public void ShowSelection()
    {
		if(getSupportActionBar().isShowing() == false)
			getSupportActionBar().show();
		switchContent(Fragment_NewBattle.Instance());
    	Session S = ParseFacebookUtils.getSession();
    	if(S != null)
    	{
    		Fragment_NewBattle.Instance().makeMeRequest(S);
    		UpdatePlayerInfo(false);
    	}
    	
    	if(getSlidingMenu() != null)
			getSlidingMenu().setSlidingEnabled(true);
    }
	
	public void UpdatePlayerInfo(boolean Force)
    {
    	ParseUser PU = ParseUser.getCurrentUser();
    	if(PU == null)
    		return;
    	
    	if(Force == false)
    	{
	    	if(m_IsParseUserInfoFetched)
	    	{
	    		PBUtility.LOG("Already Got! Parse User Info");
	    		Fragment_NewBattle.Instance().ShowPlayerInfo();
	    		return;
	    	}    	
    	}
    	    	
    	final int OldLevel =  SelfieBattleApplication.Instance().CalculateLevel( PU.getInt("BattleWin"));
    	
    	
    	
		PU.fetchInBackground(new GetCallback<ParseUser>() 
							{

								@Override
								public void done(ParseUser object, ParseException e) 
								{
									if(e == null)
									{
										m_IsParseUserInfoFetched = true;
										SelfieBattleApplication.Instance().LoadAPPFriendList();
										
										int Level = SelfieBattleApplication.Instance().CalculateLevel( object.getInt("BattleWin"));
										if(Level == 0)
											Level = 1;
										String text = "Level: " + Level;
										
										int OldLevelTemp = OldLevel;
										if(OldLevelTemp == 0)
											OldLevelTemp = 1;													
										
						        		
						        		SelfieBattleApplication app = SelfieBattleApplication.Instance();
						        		text = text + " ( " + app.GetPlayerTitle(object) + " ) "; 
						        		
						        		Fragment_NewBattle.Instance().ShowPlayerInfo();
						        		
						        		if(OldLevelTemp < Level)
										{
											// level up
						        			ShowLevelupPopup(Level, object);
										}
							        										        	
							        	
							        	
							        	
									}
									
								}
							});
		 
    }
	
	private void ShowLevelupPopup(int NewLevel, ParseUser object)
    {
		if(m_IsOnBackground == false)
		{
			String Title = SelfieBattleApplication.Instance().GetPlayerTitle(object);
    	
	    	new AlertDialog.Builder(this)
	        .setPositiveButton(R.string.ok, null)
	        .setTitle(R.string.Levelup)
	        .setMessage(getResources().getString(R.string.LevelupText, NewLevel, Title))
	        .setIcon(getResources().getDrawable( R.drawable.fblike ))
	        .show();
		}
    	
    }
	
	@Override
	public void onBackPressed() 
	{
		// TODO Auto-generated method stub
		
		if(getSlidingMenu() != null)
		{
			if(this.GetActiveFragment() != null && this.GetActiveFragment() instanceof Fragment_Login )
			{
				super.onBackPressed();
			}
			else
			{
				getSlidingMenu().toggle();
			}
		}
		else
			super.onBackPressed();
		
	}
	
	/*
	private void BackPressExit()
	{
		DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() 
		{
		    @Override
		    public void onClick(DialogInterface dialog, int which) 
		    {
		        switch (which)
		        {
		        case DialogInterface.BUTTON_POSITIVE:
		            //Yes button clicked
		        	BackPressExitYes();
		            break;

		        case DialogInterface.BUTTON_NEGATIVE:
		            //No button clicked
		            break;
		        }
		    }
		};

		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("Log Out");
		builder.setIcon(getResources().getDrawable( R.drawable.ic_dialog_info ));
		
		builder.setMessage("Are you sure you want to exit?").setPositiveButton("Confirm", dialogClickListener)
		    .setNegativeButton("Cancel", dialogClickListener).show();
	}
	*/
	
	/*
	private void BackPressExitYes()
	{
		this.finish();
	}
	*/
	
	
	
	public void switchContent(Fragment fragment) 
	{
		
		
		Fragment OldFrag = null;
		if(mContent != null)
		{
			OldFrag = mContent;
		}
		
		mContent = fragment;		
		FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
		
		if(mContent.isAdded()) 
		{
			if(OldFrag != null)
				transaction.hide(OldFrag);
		    transaction.show(mContent);
		    PBUtility.LOG("show frag");
		}
		else 
		{
			if(OldFrag != null)
				transaction.hide(OldFrag);
			transaction.add(R.id.content_frame, mContent);
		    //transaction.replace(R.id.content_frame, mContent);
			PBUtility.LOG("replace frag");
		    
		}
		
		try
		{
			transaction.commit();				
			getSlidingMenu().showContent();
		}
		catch (Exception e) 
		{
			// TODO: handle exception
		}
	}
	
	@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
		PBUtility.LOG("test activity result requestcode " + requestCode + " resultcode " + resultCode );
        super.onActivityResult(requestCode, resultCode, data);
        
        final int PARSE_REQUEST_CODE = 32665;
        if(requestCode == PARSE_REQUEST_CODE)
        {
        	ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data);        	
        }
        else
        {
        	uiHelper.onActivityResult(requestCode, resultCode, data);
        }
        
    }
	
	public void requestPublishPermissions(Session session, int ACTIVITY_CODE) 
    {
        if (session != null) 
        {
            Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, PERMISSION)
                    // demonstrate how to set an audience for the publish permissions,
                    // if none are set, this defaults to FRIENDS
                    .setDefaultAudience(SessionDefaultAudience.EVERYONE)
                    .setRequestCode(ACTIVITY_CODE);
            session.requestNewPublishPermissions(newPermissionsRequest);
        }
    }					
	
	
	private byte[] getByteArray(List<GraphUser> users) 
    {
        // convert the list of GraphUsers to a list of String where each element is
        // the JSON representation of the GraphUser so it can be stored in a Bundle
        List<String> usersAsString = new ArrayList<String>(users.size());

        for (GraphUser user : users) 
        {
            usersAsString.add(user.getInnerJSONObject().toString());
        }
        try 
        {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            new ObjectOutputStream(outputStream).writeObject(usersAsString);
            return outputStream.toByteArray();
        } 
        catch (IOException e)
        {
        	PBUtility.LOG("Unable to serialize users.");
        }
        return null;
    }

    private List<GraphUser> restoreByteArray(byte[] bytes) {
        try {
            @SuppressWarnings("unchecked")
            List<String> usersAsString =
                    (List<String>) (new ObjectInputStream(new ByteArrayInputStream(bytes))).readObject();
            if (usersAsString != null) {
                List<GraphUser> users = new ArrayList<GraphUser>(usersAsString.size());
                for (String user : usersAsString) {
                    GraphUser graphUser = GraphObject.Factory
                            .create(new JSONObject(user), GraphUser.class);
                    users.add(graphUser);
                }
                return users;
            }
        } 
        catch (ClassNotFoundException e) 
        {
        	PBUtility.LOG("Unable to deserialize users.");
        } 
        catch (IOException e) 
        {
        	PBUtility.LOG("Unable to deserialize users.");
        } 
        catch (JSONException e) 
        {
        	PBUtility.LOG("Unable to deserialize users.");
        }
        return null;
    }


}
